              package com.java.diagnostics.visualizer.parser.vgc;
              
              import com.java.diagnostics.visualizer.data.DataLevel;
              import com.java.diagnostics.visualizer.data.SourceData;
              import com.java.diagnostics.visualizer.data.StructuredData;
              import com.java.diagnostics.visualizer.data.TupleData;
              import com.java.diagnostics.visualizer.data.UnstructuredData;
              import com.java.diagnostics.visualizer.data.axes.AxisPair;
              import com.java.diagnostics.visualizer.data.axes.XDataAxis;
              import com.java.diagnostics.visualizer.data.axes.YDataAxis;
              import com.java.diagnostics.visualizer.factory.DataFactory;
              import com.java.diagnostics.visualizer.factory.SourceDataFactory;
              import com.java.diagnostics.visualizer.gc.defaultextensions.util.Messages;
              import com.java.diagnostics.visualizer.impl.factory.LogFactory;
              import com.java.diagnostics.visualizer.parser.vgc.converters.GCNumberConverter;
              import java.text.MessageFormat;
              import java.util.HashSet;
              import java.util.Set;
              import java.util.logging.Logger;
              
              public abstract class VGCPlainTextParser
                implements InstanceVGCParser
              {
                protected boolean isGoodData = false;
                protected static final String PARSE_METHOD = "parse";
                protected static final SourceDataFactory SOURCE_DATA_FACTORY = SourceDataFactory.getFactory();
                protected static final double MILLISECONDS_PER_SECOND = 1000.0D;
                protected GCNumberConverter gcNumberConverter;
                private static final String INTERNAL_ERROR_OR_CORRUPTED_LOG_NEST_DEPTH_IS_0 = Messages.getString("VGCPlainTextParser.nest.depth.error");
              
                private static final Logger TRACE = LogFactory.getTrace(VGCPlainTextParser.class);
              
                protected static final VGCParserPreferenceHelper PLUGIN_PREFERENCES = new VGCParserPreferenceHelper();
                protected boolean filterSystemGCs;
                protected boolean isSys = true;
                protected static final int UNSET = -1;
                private static final String VM_RESTART_WARNING_CONTENTS = Messages.getString("StrictJ950VGCParser.vm.restart.warning");
                protected static final String EMPTY_STRING = "";
                protected int currentGCNumber = 0;
              
                protected String currentComment = "";
              
                protected SourceData sourceData = null;
              
                protected final String className = getClass().getName();
              
                private boolean goodTimestamp = false;
              
                protected double previousTimestamp = -1.0D;
              
                protected double runningTimestamp = 0.0D;
                private Set tuples;
                private int restartCount = -1;
                protected VGCDataManager dataManager;
              
                protected final void addDataPoint(String fieldName, double y)
                {
                  addDataPoint(fieldName, y, this.currentComment);
                }
              
                protected final void addDataPoint(String fieldName, double y, String comment)
                {
                  if ((!this.isSys) || (!this.filterSystemGCs))
                  {
                    this.dataManager.addPoint(fieldName, y, comment);
                  }
                }
              
                protected boolean haveTimestamp()
                {
                  return this.goodTimestamp;
                }
              
                protected final void voidTimestamp() {
                  this.goodTimestamp = false;
                }
              
                protected abstract boolean isTimeStampRelative();
              
                protected final void setCurrentTimestamp(double time)
                {
                  this.isGoodData = true;
                  double adjustedTime = time;
                  adjustedTime += (isTimeStampRelative() ? this.runningTimestamp : 0.0D);
              
                  adjustedTime = Math.round(adjustedTime * 1000.0D) / 
                    1000.0D;
              
                  this.goodTimestamp = true;
              
                  if (time != -1.0D) {
                    this.previousTimestamp = time;
                  }
                  this.dataManager.setX(adjustedTime);
                  this.currentGCNumber += 1;
                }
              
                protected final void addData(UnstructuredData data)
                {
                  this.sourceData.addData(data, DataLevel.VARIANT);
                }
              
                protected final void addData(TupleData data) {
                  this.sourceData.addData(data, DataLevel.VARIANT);
                }
              
                protected final void addData(StructuredData data) {
                  this.sourceData.addData(data, DataLevel.VARIANT);
                }
              
                protected void initialiseAndClean()
                {
                  this.currentGCNumber = 0;
                  this.currentComment = "";
              
                  this.tuples = new HashSet();
                }
              
                protected TupleData prepareTupleData(DataFactory factory, String label, String displayName, XDataAxis xAxis, YDataAxis yAxis)
                {
                  AxisPair axisPair = factory.createAxisPair(xAxis, yAxis);
                  return prepareTupleData(factory, label, displayName, axisPair);
                }
              
                protected TupleData prepareTupleData(DataFactory factory, String label, String displayName, AxisPair axisPair)
                {
                  TupleData newTuple = factory.createTupleData(label, displayName, axisPair);
                  this.tuples.add(newTuple);
                  return newTuple;
                }
              
                protected void writeOutSourceData() {
                  if (this.isGoodData)
                  {
                    if (this.restartCount > 1) {
                      String message = MessageFormat.format(
                        VM_RESTART_WARNING_CONTENTS, 
                        new Object[] { Integer.valueOf(this.restartCount) });
                      UnstructuredData restarts = factory.createUnstructuredData(
                        "VGCLabels.restart.warning", 
                        Messages.getString("VGCLabels.restart.warning"), 
                        message);
                      this.sourceData.addData(restarts, DataLevel.VARIANT);
                    }
              
                    addVersion();
                  }
                }
              
                protected void addVersion()
                {
                }
              
                protected void logRestart()
                {
                  this.runningTimestamp = this.dataManager.getCurrentX();
              
                  this.restartCount += 1;
              
                  if (this.restartCount >= 0)
                    addDataPoint("VGCLabels.jvm.restarts", 1.0D, "");
                }
              
                protected int getRestartCount()
                {
                  return this.restartCount;
                }
              }

